package com.tencent.FaceTrackFaceu;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;

import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;

import android.widget.TextView;
import java.io.DataOutputStream;
import java.io.ByteArrayOutputStream;
import android.graphics.Color;
import com.tencent.youtufacetrack.YoutuFaceTrack;
import com.tencent.ytcommon.util.YTCommonInterface;

import com.tencent.FaceTrackFaceu.CameraPreview;


public class MainActivity extends Activity implements Camera.PreviewCallback
{
    private CameraPreview camPreview;

    private DrawView drawView;

    private TextView infoView;

    private YoutuFaceTrack facetrack = YoutuFaceTrack.getInstance();
    private byte[] FrameData = null;

    //for native call
   // private NativeInterface.FaceStatus[] s = null;
    //for java call
    private YoutuFaceTrack.FaceStatus [] s = null;
    private int sw;
    private int sh;
    private boolean bProcessing = false;

    Handler mHandler = new Handler(Looper.getMainLooper());



    static public void decodeYUV420SP(int[] rgba, byte[] yuv420sp, int width,
                                      int height) {


        final int frameSize = width * height;
// define variables before loops (+ 20-30% faster algorithm o0`)
        int r, g, b, y1192, y, i, uvp, u, v;
        for (int j = 0, yp = 0; j < height; j++) {
            uvp = frameSize + (j >> 1) * width;
            u = 0;
            v = 0;
            for (i = 0; i < width; i++, yp++) {
                y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                y1192 = 1192 * y;
                r = (y1192 + 1634 * v);
                g = (y1192 - 833 * v - 400 * u);
                b = (y1192 + 2066 * u);

// Java's functions are faster then 'IFs'
                r = Math.max(0, Math.min(r, 262143));
                g = Math.max(0, Math.min(g, 262143));
                b = Math.max(0, Math.min(b, 262143));

                // rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) &
                // 0xff00) | ((b >> 10) & 0xff);
                // rgba, divide 2^10 ( >> 10)
                rgba[yp] = ((r << 14) & 0xff000000) | ((g << 6) & 0xff0000)
                        | ((b >> 2) | 0xff00);
            }
        }
    }


    public static byte[] integersToBytes(int[] values) throws java.io.IOException{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(baos);
        for (int i = 0; i < values.length; ++i) {
            dos.writeInt(values[i]);
        }
        return baos.toByteArray();
    }


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        //Remove title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.main);

        infoView = (TextView) findViewById(R.id.info);

        drawView = (DrawView) findViewById(R.id.drawView);

        camPreview = (CameraPreview)findViewById(R.id.camPreview);
        camPreview.setCameraPreviewCallback(this);

        /**init type 1*/
        //  int licRes = YoutuFaceTrack.initLicenceStr(this, "MkHG1Ris4P11UnBlhZJXZzFHF0L8kRdzkFhXx+i3dyY71tyYUJ9eN6ZRDirM6BQ8QK55xPk0gO+fNRjjnO+geJZ4FidQzjLbOVdm6GD22jlW7ExK5zdgt0QfsYVHtIJl+TJo73BsVDD3sKycpBeihE2ICC93N/RjLQsDmYKoZcobh7JiXBsBw/TiL4B9VGOzBhWdgE8jat0xkWuqM+9vAqvIwxpIeJccC+PUZy5hC0nGNr/4zmU3zhtgMY86HfVChyfqzlLu7vdJVObIz072eHaOhzz/0faP7gCVNFaDllkNEy+eIFVZPeOhkTALNjQojCPLLnowvM+lvcSdPncoRw==");
        //  Log.d("pancheng", "lic res : "+licRes);

        //  facetrack.init(this,"",1,true);
        /**init type 1 end */

        /**init type 0*/
        //YTCommonInterface.initAuth(this, "com_tencent.licence",0, true);
        YTCommonInterface.initAuth(this, "YTFaceSDK.licence",0, true);
        /**init type 0 end*/

        initModel();
    }


    @Override
    public void onResume()
    {
        super.onResume();
        drawView.setPoints(null, sw, sh);
        infoView.setText("");

        camPreview.onResume();
    }

    @Override
    public void onPause()
    {
        camPreview.onPause();

        drawView.setPoints(null, sw, sh);
        infoView.setText("");
        super.onPause();
    }

    private void initModel()
    {
        byte[] ufdmtccbin = null;
        byte[] ufatbin = null;

        try
        {
            {
                InputStream assetsInputStream = getAssets().open("ufdmtcc.bin");
                int available = assetsInputStream.available();
                ufdmtccbin = new byte[available];
             //   Log.d("FaceTrack", "ufdmtccbin size : "+ ufdmtccbin.length);
                int byteCode = assetsInputStream.read(ufdmtccbin);
                assetsInputStream.close();
            }
            {
                InputStream assetsInputStream = getAssets().open("ufat.bin");
                int available = assetsInputStream.available();
                ufatbin = new byte[available];
                int byteCode = assetsInputStream.read(ufatbin);
                assetsInputStream.close();
            }

            facetrack.Init(ufdmtccbin, ufatbin);
        }
        catch (IOException e)
        {
            Log.e("FaceTrack", "initModel error");
        }
    }

    @Override
    public void onPreviewFrame(byte[] arg0, Camera arg1)
    {
        // At preview mode, the frame data will push to here.
        if ( !bProcessing )
        {
            FrameData = arg0;
            mHandler.post(DoImageProcessing);
        }
    }

    private Runnable DoImageProcessing = new Runnable()
    {
        public void run()
        {
            bProcessing = true;

            Camera.Size previewSize = camPreview.getCameraPreviewSize();
            int imagewidth = previewSize.width;
            int imageheight = previewSize.height;
            int imageFormat = camPreview.getCameraImageFormat();

            if (FrameData == null)
            {
                bProcessing = false;
                return;
            }
      

            //call from native. test yuv input
          //  s =nativeInterface.testNativeProcess(FrameData,imagewidth , imageheight);

            //call from java
            s = facetrack.DoDetectionProcessYUV(FrameData,imagewidth , imageheight);
            Log.d("pancheng"," get s");

            //test rgba input. test rgba input
            /*
            try {
                int rgba[] = new int[imagewidth * imageheight];
                decodeYUV420SP(rgba, FrameData, imagewidth, imageheight);
                byte rgbaByteArray[] = integersToBytes(rgba);
               // byte rgbaByteArray[] = int2byte(rgba);
                Log.e("FaceTrack", "rgbaByteArray size " + rgbaByteArray.length);
                s = nativeInterface.testNativeProcessRGBA(rgbaByteArray, imagewidth, imageheight);
                if (s == null)
                    Log.e("FaceTrack", "s:null");
                else
                    Log.e("FaceTrack", "s " + s.length);
            }catch (java.io.IOException e){

            }*/


            // rotate
            sw = imageheight;
            sh = imagewidth;

            drawView.setPoints(s, sw, sh);

            infoView.post(new Runnable() {
                public void run() {

                    if (s == null || s.length ==0 )
                    {
                        infoView.setText("没有人脸");
                    }
                    else
                    {
                       // infoView.setText(String.valueOf(s[0].pitch) + " "+ String.valueOf(s[0].yaw)+" " + String.valueOf(s[0].roll));
                        infoView.setText(String.valueOf(s[0].illumination_score));
                    }

                }
            });

            bProcessing = false;
        }
    };

}
